package StoneLabyrinth;

import Common.Game;
import javax.swing.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;

/**
 * Created by IntelliJ IDEA.
 * Author：Lick
 * Date Created in 2023-03-17
 * Time：16:24
 */
public class MainFrame extends JFrame implements KeyListener , Game {
    // 创建二维数组存储数据
    int[][] date = {
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12},
            {13, 14, 15, 0}
    };
    int [][] win = {
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12},
            {13, 14, 15, 0}
    };
    // 统计步数
    int count;
    // 0号元素行坐标位置
    int row;
    // 0号元素纵坐标位置
    int column;

    // 因为构造方法一new对象就会执行
    public MainFrame() {
        //  使用this关键字调用当前类对象
        //      1)窗体对象
        //      2)KeyListener实现类对象
        //  窗体对象.addKeyListener(KeyListener实现类对象);
        this.addKeyListener(this);
        // 初始化窗体
        initFrame();
        // 初始化数据
        initDate();
        // 移动方法
        // 绘制游戏界面
        paintView();
        // 设置窗口可见
        setVisible(true);
    }

    // 初始化数据(打乱二维数组)
    public void initDate() {
        // 准备Random对象
        Random random = new Random();
        // 遍历二维数组，获取到每一个元素
        for (int i = 0; i < date.length; i++) {
            for (int j = 0; j < date[i].length; j++) {
                int randomX = random.nextInt(4);
                int randomY = random.nextInt(4);
                // date[i][j] 和 随机索引所指向的元素进行交换
                // date[randomX][randomY]
                int temp = date[i][j];
                date[i][j] = date[randomX][randomY];
                date[randomX][randomY] = temp;
            }
        }
        for (int i = 0; i < date.length; i++) {
            for (int j = 0; j < date[i].length; j++) {
                if (date[i][j] == 0) {
                    row = i;
                    column = j;
                }
            }
        }
    }

    /**
     * 此方法用于初始化窗体
     */
    public void initFrame() {
        // 设置宽高
        setSize(514, 595);
        // 设置关闭模式
        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        // 设置标题
        setTitle("石头迷阵单机版V1.0 © 开发无厘头");
        // 设置始终显示在最上层
        setAlwaysOnTop(true);
        // 设置默认窗口居中
        setLocationRelativeTo(null);
        // 取消窗体默认布局
        setLayout(null);
    }

    /**
     * 此方法用于绘制游戏界面
     */
    public void paintView() {
        // 每次绘制之前清空重新填充
        getContentPane().removeAll();
        if (victory()){
            // 加载胜利图片资源，添加到窗体中
            JLabel label = new JLabel(new ImageIcon("images/StoneLabyrinth/win.png"));
            label.setBounds(124,230,266,88);
            getContentPane().add(label);
        }
        // 创建按钮对象
        JButton button = new JButton("重新游戏");
        button.setBounds(350,20,100,20);
        getContentPane().add(button);
        button.setFocusable(false);
        // 为按钮绑定事件监听
        button.addActionListener(e -> {
            count = 0;
            initDate();
            paintView();
        });
        // 创建JLabel对象
        JLabel label = new JLabel("步数为："+count);
        label.setBounds(50,20,100,20);
        getContentPane().add(label);
        // 创建JLabel对象
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                JLabel imgeLabel = new JLabel(new ImageIcon("images/StoneLabyrinth/" + date[i][j] + ".png"));
                imgeLabel.setBounds(50 + 100 * j, 90 + 100 * i, 100, 100);
                // 以下方法来自JFrame类  本类已继承JFrame类 所以不需要使用变量名来调用方法 该方法子类没有重写过 可以省略super关键字 直接使用即可
                getContentPane().add(imgeLabel);
            }
        }
        // 设置背景图
        JLabel background = new JLabel(new ImageIcon("/Users/lck/Desktop/img/background.png"));
        background.setBounds(26, 30, 450, 484);
        getContentPane().add(background);
        // 添加完成以后需要进行一次刷新操作(通知面板做一次刷新)
        getContentPane().repaint();

    }

    /**
     * 判断游戏是否胜利
     * @return
     */
    public boolean victory(){
        for (int i = 0; i < date.length; i++) {
            for (int j = 0; j < date[i].length; j++) {
                if (date[i][j]!=win[i][j]){
                    return false;
                }
            }
        }
        return true;
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();
        move(keyCode);
        // 每次移动之后，都重新绘制游戏界面
        paintView();
    }

    /**
     * 此方法用于处理移动业务
     */
    private void move(int keyCode) {
        if (victory()){
            return;
        }
        if (keyCode == 37) {
            if (column == 3) {
                return;
            }
            // 空白块和右侧数据交换
            // data[row][column]  data[row][column+1]
            int temp = date[row][column];
            date[row][column] = date[row][column + 1];
            date[row][column + 1] = temp;
            column++;
            count++;
        } else if (keyCode == 38) {
            if (row == 3) {
                return;
            }
            // 空白块和下面的数据交换
            // data[row][column]   data[row+1][column]
            int temp = date[row][column];
            date[row][column] = date[row + 1][column];
            date[row + 1][column] = temp;
            row++;
            count++;
        } else if (keyCode == 39) {
            if (column == 0) {
                return;
            }
            // 空白块和左侧的数据交换
            // data[row][column]   data[row][column-1]
            int temp = date[row][column];
            date[row][column] = date[row][column - 1];
            date[row][column - 1] = temp;
            column--;
            count++;
        } else if (keyCode == 40) {
            if (row == 0) {
                return;
            }
            // 空白块和上面的数据交换
            // data[row][column]   data[row-1][column]
            int temp = date[row][column];
            date[row][column] = date[row - 1][column];
            date[row - 1][column] = temp;
            row--;
            count++;
        } else if (keyCode == 90) {
            // 出发作弊器
            date = new int[][]{
                    {1, 2, 3, 4},
                    {5, 6, 7, 8},
                    {9, 10, 11, 12},
                    {13, 14, 15, 0}
            };
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void run() {

    }
}
